﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace LightCAD.MathLib.CSG
{
   class BBox3
    {
        public Vec3 minp, maxp;
        public BBox3()
        {
            minp = new Vec3(double.MaxValue, double.MaxValue,double.MaxValue);
            maxp = new Vec3(-double.MaxValue, -double.MaxValue,-double.MaxValue);
        }
        public BBox3(Vec3 minp, Vec3 maxp)
        {
            this.minp = minp.clone();
            this.maxp = maxp.clone();
        }
        public BBox3(BBox3 box)
        {
            this.minp = box.minp.clone();
            this.maxp = box.maxp.clone();
        }

        [MethodImpl((MethodImplOptions)768)]
        public bool isEmpty()
        {
            return this.maxp.x < this.minp.x || this.maxp.y < this.minp.y || this.maxp.z < this.minp.z;
        }
        public Vec3 dim()
        {
            return this.maxp - this.minp;
        }
        public double surfaceArea()
        {
            Vec3 d = dim();
            return 2 * (d.y * d.z + d.x * d.z + d.x * d.y);
        }

        public override string ToString()
        {
            return $"(min:{this.minp}, max:{this.maxp})";
        }


        [MethodImpl((MethodImplOptions)768)]
        public static bool isIn(Vec3 p, BBox3 bb)
        {
            return bb.minp.x <= p.x && p.x <= bb.maxp.x &&
                   bb.minp.y <= p.y && p.y <= bb.maxp.y &&
                   bb.minp.z <= p.z && p.z <= bb.maxp.z;
        }

        public static bool hasIsct(BBox3 lhs, BBox3 rhs)
        {
            return lhs.minp.x <= rhs.maxp.x && lhs.maxp.x >= rhs.minp.x &&
                   lhs.minp.y <= rhs.maxp.y && lhs.maxp.y >= rhs.minp.y &&
                   lhs.minp.z <= rhs.maxp.z && lhs.maxp.z >= rhs.minp.z;
        }

        public static BBox3 convex(BBox3 lhs, BBox3 rhs)
        {
            return new BBox3(Vec3.min(lhs.minp, rhs.minp), Vec3.max(lhs.maxp, rhs.maxp));
        }
        public static BBox3 isct(BBox3 lhs, BBox3 rhs)
        {
            return new BBox3(Vec3.max(lhs.minp, rhs.minp), Vec3.min(lhs.maxp, rhs.maxp));
        }
    }
}
